home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 4 / QRZ Ham Radio Callsign Database - Volume 4.iso / files / dsp / 56ktools / a5611.tz / a5611 / main.c < prev    next >
C/C++ Source or Header  |  1992-08-11  |  7KB  |  402 lines

  1. /*******************************************************
  2.  *
  3.  *  a56 - a DSP56001 assembler
  4.  *
  5.  *  Written by Quinn C. Jensen
  6.  *  July 1990
  7.  *  jensenq@npd.novell.com (or jensenq@qcj.icon.com)
  8.  *
  9.  *******************************************************\
  10.  
  11. /*
  12.  * Copyright (C) 1990-1992 Quinn C. Jensen
  13.  *
  14.  * Permission to use, copy, modify, distribute, and sell this software
  15.  * and its documentation for any purpose is hereby granted without fee,
  16.  * provided that the above copyright notice appear in all copies and
  17.  * that both that copyright notice and this permission notice appear
  18.  * in supporting documentation.  The author makes no representations
  19.  * about the suitability of this software for any purpose.  It is
  20.  * provided "as is" without express or implied warranty.
  21.  *
  22.  */
  23. static char *Copyright = "Copyright (C) 1990-1992 Quinn C. Jensen";
  24.  
  25. /*
  26.  *  main.c - The "main" code for the assembler.
  27.  *
  28.  */
  29.  
  30. #include "a56.h"
  31.  
  32. #define MAX 1024
  33.  
  34. int pass;
  35. int error;
  36. extern unsigned long pc;
  37. extern int seg;
  38. BOOL binary_listing = FALSE;
  39. BOOL list_includes = FALSE;
  40. FILE *obj = NULL;
  41. BOOL list_on = TRUE;
  42. char *alloc();
  43.  
  44. main(argc,argv)
  45. int argc;
  46. char *argv[];
  47. {
  48.     int i;
  49.     extern char *optarg;
  50.     extern int optind;
  51.     int c;
  52.     char *output_file = "a56.out";
  53.     char *input_file;
  54.  
  55.     while((c = getopt(argc, argv, "blo:")) != EOF) switch (c) {
  56.     case 'b':
  57.         binary_listing++;
  58.         break;
  59.     case 'l':
  60.         list_includes++;
  61.         break;
  62.     case 'o':
  63.         output_file = optarg;
  64.         break;
  65.     case '?':
  66.     default:
  67.         fatal("usage: a56  [-b]  [-l]  [-o output-file]  input-file\n");
  68.     }
  69.     input_file = argv[optind++];
  70.     obj = open_write(output_file);
  71.  
  72.     pc = 0;
  73.     seg = 0;
  74.     pass = 1;
  75.     reset_psects();
  76.     include(input_file);
  77.  
  78.     pc = 0;
  79.     seg = 0;
  80.     pass = 2;
  81.     reset_psects();
  82.     include(input_file);
  83.  
  84.     dump_symtab();
  85.     fclose(obj);
  86.     printf("errors=%d\n", error);
  87.     return(error ? 1 : 0);
  88. }
  89.  
  90. struct inc inc[MAX_NEST];
  91. int inc_p = 0;
  92.  
  93. include(file)
  94. char *file;
  95. {
  96.     FILE *fp = open_read(file);
  97.     extern FILE *yyin;
  98.  
  99.     inc_p++;
  100.     if(inc_p >= MAX_NEST)
  101.     fatal("%s: include nesting too deep\n", file);
  102.  
  103.     inc[inc_p].file = file;
  104.     inc[inc_p].fp = fp;
  105.     inc[inc_p].line = 0;
  106.  
  107.     list_on = TRUE;
  108.     if(inc_p > 1 && NOT list_includes)
  109.     list_on = FALSE;
  110.  
  111.     yyin = inc[inc_p].fp;
  112.     if(inc_p == 1)
  113.     yyparse();
  114. }
  115.  
  116. yywrap()
  117. {
  118.     fclose(inc[inc_p].fp);
  119.     inc_p--;
  120.     list_on = TRUE;
  121.     if(inc_p > 1)
  122.     list_on = FALSE;
  123.     if(inc_p) {
  124.     yyin = inc[inc_p].fp;
  125.     return(0);
  126.     } else {
  127.     return(1);
  128.     }
  129. }
  130.  
  131. struct n
  132. sym_ref(sym)    /* return symbol value or UNDEF if not defined yet */
  133. char *sym;
  134. {
  135.     struct sym *sp, *find_sym();
  136.     struct n result;
  137.  
  138.     result.type = UNDEF;
  139.  
  140.     sp = find_sym(sym);
  141.     if(NOT sp) {
  142.     if(pass == 2) {
  143.         yyerror("%s: undefined symbol", sym);
  144.     }           
  145.     return result;
  146.     }
  147.  
  148.     return sp->n;
  149. }
  150.  
  151. #define HASHSIZE 128
  152.  
  153. #define HASH(sym) (((sym)[0] ^ sym[1]) % HASHSIZE)
  154.  
  155. struct sym *symtab[HASHSIZE];
  156.  
  157. sym_def(sym, type, i, f)
  158. char *sym;
  159. int type;
  160. int i;
  161. double f;
  162. {
  163.     struct sym *sp, **stop, *find_sym();
  164.  
  165.     if(pass == 1) {
  166.     if(find_sym(sym)) {
  167.         pass = 2;        /* what a kludge */
  168.         yyerror("%s: multiply defined symbol", sym);
  169.         pass = 1;
  170.         return;
  171.     }
  172.     stop = &symtab[HASH(sym)];
  173.     sp = NEW(struct sym);
  174.     sp->next = *stop;
  175.     *stop = sp;
  176.     sp->name = strsave(sym);
  177.     sp->n.type = type;
  178.     if(type == INT)
  179.         sp->n.val.i = i & 0xFFFFFF;
  180.     else
  181.         sp->n.val.f = f;
  182.     } else {
  183.     sp = find_sym(sym);
  184.     if(NOT sp)
  185.         fatal("internal error 304\n");
  186.     if(sp->n.type != type ||
  187.         type == INT && sp->n.val.i != (i & 0xFFFFFF) ||
  188.         type == FLT && sp->n.val.f != f)
  189.         yyerror("%s: assembler phase error", sym);
  190.     }    
  191. }
  192.  
  193. struct sym *find_sym(sym)
  194. char *sym;
  195. {
  196.     struct sym *sp, **stop;
  197.  
  198.     stop = &symtab[HASH(sym)];
  199.     for(sp = *stop; sp; sp = sp->next)
  200.     if(strcmp(sp->name, sym) == 0)
  201.         return(sp);
  202.     
  203.     return(NULL);
  204. }
  205.  
  206. dump_symtab()
  207. {
  208.     struct sym *sp, **stop;
  209.     int i;
  210.  
  211.     printf("\nSymbol Table\n");
  212.  
  213.     for(i = 0, stop = symtab; i < HASHSIZE; i++, stop++) {
  214.     for(sp = *stop; sp; sp = sp->next) {
  215.         if(sp->n.type == INT)
  216.         printf("%16s %06X\n", sp->name, sp->n.val.i);
  217.         else
  218.         printf("%16s %20.10f\n", sp->name, sp->n.val.f);
  219.     }
  220.     }   
  221. }
  222.  
  223. char *printcode(word)
  224. int word;
  225. {
  226.     static char list[MAX], *lp;
  227.     int i;
  228.  
  229.     word &= 0xFFFFFF;
  230.  
  231.     if(binary_listing) {
  232.     sprintf(list, "%06X<", word);
  233.     for(i = 0, lp = &list[7]; i < 24; i++, lp++) {
  234.         *lp = word & 1 << 23 - i ? '1' : '0';
  235.         if(i && i % 4 == 3)
  236.         *++lp = i % 8 == 7 ? ' ' : ',';
  237.     }
  238.     lp[-1] = '>';
  239.     lp[0] = '\0';
  240.     } else {
  241.     sprintf(list, "%06X", word);
  242.     }
  243.     return(list);
  244. }
  245.  
  246. char *spacespace[2] = {
  247. /*P:XXXX_XXXXXX_*/
  248.  "              ",
  249. /*P:XXXX_XXXXXX(XXXX_XXXX_XXXX_XXXX_XXXX_XXXX)_*/
  250.  "                                             "};
  251. char *spaces(n)
  252. int n;
  253. {
  254.     return(&spacespace[binary_listing ? 1 : 0][n]);
  255. }
  256.  
  257. gencode(seg, pc, word)
  258. int seg, pc, word;
  259. {
  260.     extern char segs[];
  261.  
  262.     fprintf(obj, "%c %04X %06X\n", segs[seg], pc, word & 0xFFFFFF);
  263. }
  264.  
  265. char fixbuf[1024];
  266.  
  267. char *fixstring(s)
  268. char *s;
  269. {
  270.     char *bp = fixbuf;
  271.     int ival;
  272.  
  273.     while(*s) {
  274.     switch (*s) {
  275.         case '\'':
  276.         case '\"':
  277.         s++;
  278.         break;
  279.         case '\\':
  280.         switch (*++s) {
  281.             case 'b': *bp++ = '\b'; break;
  282.             case 'r': *bp++ = '\r'; break;
  283.             case 'f': *bp++ = '\f'; break;
  284.             case 'n': *bp++ = '\n'; break;
  285.             case 't': *bp++ = '\t'; break;
  286.             case '\\': *bp++ = '\\'; break;
  287.             case '0':
  288.             ival = 0;
  289.             while(*s >= '0' && *s <= '9') {
  290.                 ival <<= 3;
  291.                 ival += *s++ - '0';
  292.             }
  293.             *bp++ = ival;
  294.             break;
  295.         }
  296.         break;
  297.         default:
  298.         *bp++ = *s++;
  299.         break;
  300.     }
  301.     }
  302.     *bp = '\0';
  303.     return(fixbuf);
  304. }
  305.  
  306. #define ONE 0x4000000
  307.  
  308. makefrac(s)
  309. char *s;
  310. {
  311.     int frac = 0, div = 1;
  312.     int scale = 1;
  313.  
  314.     while(*s) {
  315.     switch(*s) {
  316.         case '-':
  317.         scale = -1;
  318.         break;
  319.         case '.':
  320.         div = 10;
  321.         break;
  322.         default:
  323.         frac += (*s - '0') * scale * ONE / div;
  324.         div *= 10;
  325.         break;
  326.     }
  327.     s++;
  328.     }
  329.  
  330.     return(frac + scale * 4 >> 3 & 0xFFFFFF);
  331. }
  332.  
  333. /***************** psect stuff ************************/
  334.  
  335. struct psect *ptop = NULL, *cur_psect = NULL;
  336.  
  337. reset_psects()
  338. {
  339.     struct psect *pp;
  340.  
  341.     for(pp = ptop; pp; pp = pp->next)
  342.     pp->pc = pp->bottom;
  343.  
  344.     set_psect(NULL);
  345. }
  346.  
  347. struct psect *find_psect(name)
  348. char *name;
  349. {
  350.     struct psect *pp;
  351.  
  352.     for(pp = ptop; pp; pp = pp->next)
  353.     if(strcmp(pp->name, name) == 0)
  354.         return(pp);
  355.  
  356.     return(NULL);
  357. }
  358.  
  359. set_psect(pp)
  360. struct psect *pp;
  361. {
  362.     cur_psect = pp;
  363. }
  364.  
  365. check_psect(seg, pc)
  366. int seg;
  367. unsigned int pc;
  368. {
  369.     if(cur_psect) {
  370.     if(seg == cur_psect->seg && pc >= cur_psect->bottom && 
  371.         pc <= cur_psect->top) {
  372.         cur_psect->pc = pc;
  373.         return(TRUE);
  374.     } else {
  375.         return(FALSE);
  376.     }
  377.     } else {
  378.     return(TRUE);
  379.     }
  380. }
  381.  
  382. struct psect *new_psect(name, seg, bottom, top)
  383. char *name;
  384. int seg;
  385. unsigned int bottom, top;
  386. {
  387.     struct psect *pp = find_psect(name);
  388.  
  389.     if(NOT pp) {
  390.     pp = (struct psect *)alloc(sizeof *pp);
  391.     pp->next = ptop;
  392.     ptop = pp;
  393.     pp->name = strsave(name);
  394.     pp->seg = seg;
  395.     pp->pc = bottom;
  396.     }
  397.     pp->bottom = bottom;
  398.     pp->top = top;
  399.  
  400.     return(pp);
  401. }
  402.